/**
 * 
 */
package project;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import project.reguli.ConstrangereLaptop;
import project.reguli.ConstrangereRadio;
import project.reguli.ConstrangereTelevizor;
import project.reguli.ConstrangereVeioza;

import jess.JessException;
import jess.Rete;

/**
 * @author Aarni
 * 
 */
public class Reguli {

	public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

	public int aplicaRegula(String numeAparat, String ora) throws JessException {

		int penalizare = 0;

		String[] tokens = ora.split(" ");
		String oraCurenta = tokens[1].split(":")[0];
		int ore = Integer.parseInt(oraCurenta);

		if (numeAparat == "Filtru cafea")
			return penalizare;

		Rete rete = new Rete();

		ConstrangereLaptop constrangereLaptop = new ConstrangereLaptop();
		ConstrangereTelevizor constrangereTelevizor = new ConstrangereTelevizor();
		ConstrangereVeioza constrangereVeioza = new ConstrangereVeioza();
		ConstrangereRadio constrangereRadio = new ConstrangereRadio();

		rete.addUserfunction(constrangereLaptop);
		rete.addUserfunction(constrangereTelevizor);
		rete.addUserfunction(constrangereVeioza);
		rete.addUserfunction(constrangereRadio);

		String expresie = "";
		try {
			expresie = "(Constrangere" + numeAparat + " " + numeAparat + " " + oraCurenta + ")";
		} catch (Exception e) {
			return 0;
		}
		penalizare += Integer.valueOf(rete.eval(expresie).toString());

		return penalizare;
	}

	public static void main(String[] args) throws JessException {
		Reguli reguli = new Reguli();

		Reader citeste = new Reader();
		Ag12.ListaValori = citeste.readData();

		Ag23.ListaValoriDistincte = scoateValorileIdentice(Ag12.ListaValori);

		List<List<DateFiltrate>> result = formeazaListe(0, Ag23.ListaValoriDistincte, Ag23.listaAparate);
		Ag34.listaDePosibilitati = ScoateInformatiiImposibile(result);

		System.out.println("Ag3");
		for (List<DateFiltrate> date : result) {
			System.out.println("lista");
			for (DateFiltrate date1 : date) {
				System.out.println(date1);
			}
		}

		for (DateFiltrate element : Ag34.listaDePosibilitati.get(0)) {
			System.out.println(element.toString());
		}

	}

	private static List<Data> scoateValorileIdentice(List<Data> datas) {

		List<Data> result = new ArrayList<Data>();
		int lastValue = -1;

		for (Data data : datas) {
			if (data.getValue() != lastValue) {
				result.add(data);
			}
			lastValue = data.getValue();
		}
		return result;
	}

	private static Boolean ListaEValida(List<DateFiltrate> lista) {
		for (int i = 0; i < lista.size() - 2; i++)
			for (int j = i + 1; j < lista.size(); j++) {
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && lista.get(i).isStatus() == lista.get(j).isStatus())
					return false;
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && lista.get(i).isStatus() && !lista.get(j).isStatus())
					break;
				if (lista.get(i).getAparat() == lista.get(j).getAparat() && !lista.get(i).isStatus() && lista.get(j).isStatus())
					break;
			}
		return true;

	}

	private static List<List<DateFiltrate>> formeazaListe(int p, List<Data> listaIntrare, List<Data> listaAparate) {
		List<List<DateFiltrate>> result = new ArrayList<List<DateFiltrate>>();
		List<DateFiltrate> listaRez = new ArrayList<DateFiltrate>();
		AdaugaAparate(result, -1, listaIntrare, listaAparate, listaRez);
		return result;
	}

	private static void AdaugaAparate(List<List<DateFiltrate>> result, int i, List<Data> listaIntrare, List<Data> listaAparate,
			List<DateFiltrate> listaRez) {
		i++;
		if (i < listaIntrare.size() - 1) {
			int diff = listaIntrare.get(i + 1).getValue() - listaIntrare.get(i).getValue();
			for (Data element : listaAparate) {
				if (element.getValue() == Math.abs(diff)) {
					if (diff > 0)
						listaRez.add(new DateFiltrate(diff, listaIntrare.get(i).getTime(), element.getTime(), listaIntrare.get(i).getValue(), true));
					else
						listaRez.add(new DateFiltrate(diff, listaIntrare.get(i).getTime(), element.getTime(), listaIntrare.get(i).getValue(), false));
					AdaugaAparate(result, i, listaIntrare, listaAparate, CopyOf(listaRez));
					listaRez.remove(listaRez.size() - 1);
				}
			}
			return;
		}
		result.add(listaRez);
	}

	private static List<DateFiltrate> CopyOf(List<DateFiltrate> lista) {
		List<DateFiltrate> result = new ArrayList<DateFiltrate>();
		for (DateFiltrate el : lista)
			result.add(el);
		return result;
	}

	private static List<List<DateFiltrate>> ScoateInformatiiImposibile(List<List<DateFiltrate>> liste) {
		List<List<DateFiltrate>> result = new ArrayList<List<DateFiltrate>>();
		for (List<DateFiltrate> lista : liste)
			if (ListaEValida(lista))
				result.add(lista);
		return result;
	}

}
